package com.lambkit.core.task.http;

import com.lambkit.core.LambkitResult;
import com.lambkit.core.LifecycleException;
import com.lambkit.core.LifecycleState;
import com.lambkit.core.http.Controller;
import com.lambkit.core.http.Handler;
import com.lambkit.core.http.HttpHandlers;
import com.lambkit.core.http.IHttpContext;
import com.lambkit.core.pipeline.IValve;
import com.lambkit.core.task.ITask;
import com.lambkit.core.task.ITaskInstance;
import com.lambkit.core.task.IWorkCenter;
import com.lambkit.core.task.WorkCenter;

/**
 * http工作中心, http独立线程，依序执行即可
 * @author yangyong(孤竹行)
 */
public class HttpWorkCenter extends WorkCenter<HttpTask, HttpTaskInstance> {

    private static ThreadLocal<HttpTaskInstance> instanceThreadLocal = new ThreadLocal<>();

    private HttpHandlers httpHandlers = new HttpHandlers();

    @Override
    public IWorkCenter addValve(Class<? extends IValve> clazz) {
//        httpHandlers.addValve((HttpValve) getApp().getBeanFactory().get(clazz));
        return this;
    }

    @Override
    public void start() throws LifecycleException {
        setCurrentState(LifecycleState.STARTED);
    }

    public void addHandler(Handler handler) {
        httpHandlers.addHandler(handler);
    }

    public void addController(String route, Class controllerClass) {
        httpHandlers.addController(route, controllerClass);
    }

    public boolean handle(IHttpContext httpContext) {
        httpHandlers.runOn(getApp().context());
        boolean flag = httpHandlers.handle(httpContext);
        if(!flag) {
            String target = httpContext.getTarget();
            //Printer.print(this, "task", getClass() + " request uri: " + target);
            ITask task = route(target);
            //Printer.print(this, "task", getClass() + " taskClass: " + task.getClass().getName());
            if(task instanceof HttpTask) {
                HttpTaskContext context = new HttpTaskContext();
                context.setUri(target);
                context.setHttpContext(httpContext);
                context.setTask((HttpTask) task);
                HttpTaskInstance taskInstance = new HttpTaskInstance(context);
                //任务实例开始执行
                execute(taskInstance);
                httpContext.renderJson(context.getResult());
                return true;
            } else {
                //httpContext.renderError(404, "Not Found");
            }
        }
        return flag;
    }

    @Override
    public void execute(ITaskInstance task) {
        if(task instanceof HttpTaskInstance) {
            execute((HttpTaskInstance) task);
        }
    }

    public void execute(HttpTaskInstance task) {
        instanceThreadLocal.set(task);
        try {
            task.start();
        } catch (LifecycleException e) {
            throw new RuntimeException(e);
        }
        instanceThreadLocal.remove();
    }

    @Override
    public LambkitResult getResult(String taskId) {
        HttpTaskInstance instance = instanceThreadLocal.get();
        if(instance != null) {
            return instance.getContext().getResult();
        }
        return null;
    }

    @Override
    public HttpTaskContext getContext(String taskId) {
        HttpTaskInstance instance = instanceThreadLocal.get();
        if(instance != null) {
            return instance.getContext();
        }
        return null;
    }

    @Override
    public HttpTaskInstance poll(String taskId) {
        HttpTaskInstance instance = instanceThreadLocal.get();
        if(instance != null) {
            instanceThreadLocal.remove();
            return instance;
        }
        return null;
    }
}
